#include "threadpool.h"


template<class T>
ThreadPool<T>::ThreadPool(int thread_num = 8, int max_requests = 10000)
    :_thread_cnt(thread_num),           // 初始化线程数量
    ,_max_requests(_max_retquests)        // 初始化最大等待处理数
    ,_stop_thread(false)                // 开始默认不终止线程
    ,_thread_Set(nullptr)               // 线程数组为空
{
    if( (_thread_num <= 0) || (_max_requests) <= 0 ){
        // 合法性判断：线程池中的线程个数、最大等待处理数
        throw std::exception();
    }
    // 创建数组
    _thread_Set = new pthread_t[_thread_cnt];
    if(!_thread_Set){
        throw std::exception();
    }   

    // 设置线程脱离！
    /*
        实现结构：
        主 => 池
        设置线程脱离，让线程资源的释放不用主线程来处理（交给操作系统）
    */
    for(int i = 0;i<_thread_cnt;i++){
        // 创建线程：
        // param callBack_Task：回调任务函数（一定是静态的！）
        if(pthread_create(_thread_Set + i, nullptr, callBack_Task, this) != 0){
            // 创建失败：释放线程数组资源，并抛出异常
            delete[] _thread_Set;
            throw std::exception();
        }

        if( pthread_detach(_thread_Set[i]) ){
            delete[] _thread_Set;
            throw std::exception();
        }
    }
}

template<class T>
ThreadPool<T>::~ThreadPool(){
    delete[] _thread_Set;
    _stop_thread = true;
}



template<class T>
bool ThreadPool<T>::Push(T* task){
    // 加锁
    _queue_locker.lock();
    if(_task_Queue.size() > _max_retquests){
        // 如果任务队列总数量超出，可等待处理的最大限度，则不入队
        _queue_locker.unlock();
        return false;
    }
    // 任务入队
    _task_Queue.push_back(task);
    _queue_locker.unlock();
    _queue_sem_stat.Post();         // 任务增加，信号量增加
    return true;
}

template<class T>
void* ThreadPool<T>::callBack_Task(void* args){
    ThreadPool* ptr_this = (ThreadPool*) args;
    ptr_this->run();
    return ptr_this;
}

/* 线程启动 */
template<class T>
void ThreadPool<T>::Run(){
    while(!_stop_thread){
        _queue_sem_stat.Wait();     // 等待获取一个线程
        _queue_locker.lock();
        if(_task_Queue().empty()){
            // 队列中没有任务
            _queue_locker.unlock();
            continue;
        }

        T* task = _task_Queue.front();  // 获取队头任务
        _task_Queue.pop_front();        // 任务出队
        _queue_locker.unlock();

        // if(!task){               // 判断任务是否是空（有问题）
        //     continue;
        // }

        task->process();
    }
}